//@author A0105730U
#include "Analyzer.h"
#include <string>
#include <assert.h>

#define FAKESERIAL 1



Analyzer::Analyzer(void){
	Invoker _theE;
	_searchId = 1;
}


//@author A0105730U
bool Analyzer::isLeapyear(int year){
	if(((year%4 == 0)&&(year%100 != 0))||(year%400 == 0)){
		return true;
	}else{
		return false;
	}
}



//@author A0105730U
//find "t[...]" in the input string(time_task) from stPos(position) to edPos(position) 
bool Analyzer::findStrictTimePiece(std::string time_task, std::string& task, size_t& stPos, size_t& edPos){
	task = time_task;

	stPos = time_task.rfind(TIME_INDICATOR_ANALYZER);
	if(stPos == std::string::npos){
		return false;
	}

	edPos = time_task.find_first_of(']', stPos);
	if(edPos == std::string::npos){
		return false;                              //format error
	}

	std::string prefix = time_task.substr(0, stPos);
	std::string suffix = time_task.substr(edPos+1, time_task.size()-edPos-1);
	task = prefix + QUOTE_BLANK_ANALYZER + suffix;
	return true;

}


//@author A0105730U
//check the validity of a DateTime, taking into consideration of leap year and different number of total days in different months
bool Analyzer::DateTimeIsValid(DateTime dt){
	if(dt.getYear()<2014 || dt.getYear()>2100 ){
		return false;
	}else if(dt.getMonth()<1 || dt.getMonth()>12){
		return false;
	}else if(dt.getHour() < 0 || dt.getHour() >= 24){
		return false;
	}else if(dt.getMin()<0 || dt.getMin()>59){
		return false;
	}else{
		int D;	
		int mm = dt.getMonth();
		if(mm == 1||mm ==3||mm ==5||mm ==7||mm ==8||mm ==10||mm ==12){
			D = 31;
		}else if(mm == 4||mm ==6||mm ==9||mm ==11){
			D = 30;
		}else{
			if(isLeapyear(dt.getYear())){
				D = 29;
			}else{
				D = 28;
			}
		}

		if(dt.getDay() < 1 || dt.getDay() > D){
			return false;
		}
	}

	return true;
}








//@author A0105730U
//Check whether the startTime is before endTime
//return true if startTime is before endTime
bool Analyzer::TwoDatesAreInOrder(DateTime startTime, DateTime endTime){
	if((startTime.getYear() < endTime.getYear())){
		return true;
	}else if((startTime.getYear() == endTime.getYear())&&(startTime.getMonth() < endTime.getMonth())){
		return true;
	}else if((startTime.getYear() == endTime.getYear())&&(startTime.getMonth() == endTime.getMonth())&&(startTime.getDay() < endTime.getDay())){
		return true;
	}else if((startTime.getYear() == endTime.getYear())&&(startTime.getMonth() == endTime.getMonth())&&(startTime.getDay() == endTime.getDay())&&(startTime.getHour() < endTime.getHour())){
		return true;
	}else if((startTime.getYear() == endTime.getYear())&&(startTime.getMonth() == endTime.getMonth())&&(startTime.getDay() == endTime.getDay())&&(startTime.getHour() == endTime.getHour())&&(startTime.getMin() < endTime.getMin())){
		return true;
	}else{
		return false;
	}
}




//@author A0105730U
// find the key word of updating original event to floating event  
bool Analyzer::checkFloating(std::string input){
	input = clear_Space_Punctuation(input);
	if((input == TO_FLOATING_EVENT_ANALYZER)||(input == TO_FLOATING_ANALYZER)||(input == TO_FLOAT_ANALYZER)||(input == FLOAT_ANALYZER)||(input == FLOATING_ANALYZER)){
		return true;
	}else{
		return false;
	}
}


//@author A0105730U
//e.g. ". !,play., !" -> "play"
std::string Analyzer::clear_Space_Punctuation(std::string s){
	size_t pos1 = s.find_first_not_of(NOT_FOUND_STRING_ANALYZER);
	size_t pos2 = s.find_last_not_of(NOT_FOUND_STRING_ANALYZER);

	if(pos1 == std::string::npos){
		return QUOTE_ANALYZER;
	}

	return s.substr(pos1, pos2-pos1+1);
}




//@author A0105730U
//transfer the time information from standard time string to datetime class
void Analyzer::fillDateTimeWithTimeString(DateTime& dt, std::string time){
	int hour;
	int mins;
	char c;
	if(time == QUOTE_ANALYZER){
		return;
	}else{
		std::istringstream in(time);
		in >> hour >> c >> mins;
		dt.setHour(hour);
		dt.setMin(mins);
		dt.setEmpty(false);
	}
}

//@author A0105730U
//transfer the date information from standard date string to datetime class
void Analyzer::fillDateTimeWithDateString(DateTime& dt, std::string date){
	int day;
	int month;
	int year;
	char c;
	if(date == QUOTE_ANALYZER){
		return;
	}else{
		std::istringstream in(date);
		in >> day >> c >> month >> c >> year;
		dt.setDay(day);
		dt.setMonth(month);
		dt.setYear(year);
		dt.setEmpty(false);
	}
}



//@author A0105730U
//split the user input to instruction and content 
void Analyzer::splitInput(std::string input, std::string& instruction, std::string& content){
	std::size_t delimiter = input.find_first_of(QUOTE_BLANK_ANALYZER);

	if(delimiter == std::string::npos){
		instruction = input;
		content = QUOTE_ANALYZER;
	}else{
		instruction = input.substr(0,delimiter-0);
		content = input.substr(delimiter+1,input.size()-delimiter-1);

	}
}


//@author A0105730U
CommandType Analyzer::getCommandType(std::string instruction){
	if(instruction == INSTRUCTION_ADD_ANALYZER){
		return CommandTypeAdd;
	}else if(instruction == INSTRUCTION_DELETE_ANALYZER){
		return CommandTypeDelete;
	}else if(instruction == INSTRUCTION_UPDATE_ANALYZER){
		return CommandTypeUpdate;
	}else if(instruction == INSTRUCTION_SEARCH_ANALYZER){
		return CommandTypeSearch;
	}else if(instruction == INSTRUCTION_DISPLAY_ANALYZER){
		return CommandTypeDisplay;
	}else if(instruction == INSTRUCTION_READ_ANALYZER){
		return CommandTypeRead;
	}else if(instruction == INSTRUCTION_DONE_ANALYZER){
		return CommandTypeMark;
	}else if(instruction == INSTRUCTION_CHECK_ANALYZER){
		return CommandTypeCheck;
	}else{
		return CommandTypeInvalid;
	}
}


//@author A0105730U
//get and retrieve ID from user input
std::string Analyzer::seperateID(std::string ID_task_time_impo, std::string& task_time_impo){
	std::size_t pos = ID_task_time_impo.find_first_not_of(QUOTE_BLANK_ANALYZER);
	pos = ID_task_time_impo.find_first_of(BLANK_COMMA_DOT_ANALYZER, pos);


	if(pos == std::string::npos){
		task_time_impo = QUOTE_ANALYZER;
		return ID_task_time_impo;
	}

	
	task_time_impo = ID_task_time_impo.substr(pos + 1, ID_task_time_impo.size() - pos);
	std::string id = ID_task_time_impo.substr(0, pos - 0);

	//remove space before and after id:
	std::size_t start = id.find_first_not_of(' ');
	std::size_t end = id.find_last_not_of(' ', id.size()-1);
	id = id.substr(start, end - start + 1);

	return id;
}

//@author A0105730U
CommandAdd Analyzer::intepret_Add(std::string task_time_loca_impo){
	// expected input: <content> <time> <importance>	
	std::string task_time_loca;
	std::string task_time;
	std::string taskS;
	std::string timeS;

	Parser_Importance parserImpo;
	std::string impo = parserImpo.check(task_time_loca_impo, task_time_loca);

	Parser_Location parserLoc;
	std::string location = parserLoc.check(task_time_loca, task_time);
	task_time = task_time + QUOTE_BLANK_ANALYZER;


	DateTime startT;                   
	DateTime endT;
	EventType etype;
	std::string startTimeString;
	std::string endTimeString;
	std::string startDateString;
	std::string endDateString;
	DateTimeLocator dtl;


	if(dtl.process(task_time, taskS, startTimeString, endTimeString, startDateString, endDateString)){
		if((startTimeString == QUOTE_ANALYZER) && (endTimeString == QUOTE_ANALYZER)){    //Assert
			etype = FLOATING;
		}else{
			if(startTimeString == QUOTE_ANALYZER){
				etype = DEADLINE;
			}else{
				etype = TIME;
			}

			fillDateTimeWithTimeString(startT, startTimeString);
			fillDateTimeWithTimeString(endT, endTimeString);
			fillDateTimeWithDateString(startT, startDateString);
			fillDateTimeWithDateString(endT, endDateString);
		}
	}else{   

		size_t stPosTime;
		size_t edPosTime;
		if(findStrictTimePiece(task_time, taskS, stPosTime, edPosTime)){
			std::string dummy;
			std::string timePiece = task_time.substr(stPosTime, edPosTime-stPosTime);

			if(dtl.process(timePiece, dummy, startTimeString, endTimeString, startDateString, endDateString)){

				if((startTimeString == QUOTE_ANALYZER) && (endTimeString == QUOTE_ANALYZER)){    //Assert
					etype = FLOATING;
				}else{

					if(startTimeString == QUOTE_ANALYZER){
						etype = DEADLINE;
					}else{
						etype = TIME;
					}

					fillDateTimeWithTimeString(startT, startTimeString);
					fillDateTimeWithTimeString(endT, endTimeString);
					fillDateTimeWithDateString(startT, startDateString);
					fillDateTimeWithDateString(endT, endDateString);
				}


			}else{
				CommandAdd add;
				add.setInvalid();
				add.setMessage(ErrorConfuse);
				return add;
			}

		}else{
			CommandAdd add;
			add.setInvalid();
			add.setMessage(ErrorConfuse);
			return add;
		}
	}



	if(etype == TIME){
		TimedEvent* eve = new TimedEvent;
		eve->setStatus(PENDING);
		eve->setName(taskS);

		eve->setImportanceLevel(impo);
		eve->setLocation(location);
		eve->setTimedEventStartTime(startT);
		eve->setTimedEventEndTime(endT);
		eve->setSearchID(_searchId);
		_searchId++;                

		CommandAdd add;

		if(!DateTimeIsValid(startT)){
			add.setMessage(ErrorWrongTime);
			add.setInvalid();
			return add;
		}

		if(!DateTimeIsValid(endT)){
			add.setMessage(ErrorWrongTime);
			add.setInvalid();
			return add;
		}


		if(!TwoDatesAreInOrder(startT, endT)){
			add.setMessage(ErrorWrongTime);
			add.setInvalid();
			return add;
		}

		add.setEvent(eve);
		return add;

	}else if(etype == DEADLINE){
		DeadlineEvent* eve = new DeadlineEvent;
		eve->setStatus(PENDING);
		eve->setName(taskS);
		
		eve->setImportanceLevel(impo);
		eve->setLocation(location);
		eve->setDeadlineEventEndtime(endT);
		eve->setSearchID(_searchId);
		_searchId++;                

		CommandAdd add;

		if(!DateTimeIsValid(endT)){
			add.setMessage(ErrorWrongTime);
			add.setInvalid();
			return add;
		}

		add.setEvent(eve);
		return add;

	}else{
		FloatingEvent* eve = new FloatingEvent;
		eve->setStatus(PENDING);
		eve->setName(taskS);

		eve->setImportanceLevel(impo);
		eve->setLocation(location);
		eve->setSearchID(_searchId);
		_searchId++;                

		CommandAdd add;
		add.setEvent(eve);
		return add;
	}
}


//@author A0105730U
CommandDelete Analyzer::intepret_Delete(std::string input){
	// expected input: <ID1> <ID2> <ID3> ....
	int id;
	std::vector<int> idVec;
	std::istringstream in(input);
	while(in >> id){
		idVec.push_back(id);
	}

	if(idVec.empty()){
		CommandDelete invalidDel;
		invalidDel.setInvalid();
		return invalidDel;
	}else{
		CommandDelete del;
		del.setID(idVec);
		return del;
	}
}


//@author A0105730U
CommandMark Analyzer::intepret_Mark(std::string input){
	// expected input: <ID1> <ID2> <ID3> ....
	int id;
	std::vector<int> idVec;
	std::istringstream in(input);
	while(in >> id){
		idVec.push_back(id);
	}

	if(idVec.empty()){
		CommandMark invalidMark;
		invalidMark.setInvalid();
		return invalidMark;
	}else{
		CommandMark mark;
		mark.setID(idVec);
		return mark;
	}
}




//@author A0105730U
CommandUpdate Analyzer::intepret_Update(std::string ID_task_time_loca_impo){
	// expected input: <id> <content> <time> <importance>	

	std::string task_time_loca_impo;
	std::string task_time_loca;
	std::string task_time;
	std::string taskS;
	std::string timeS;

	std::string ID = seperateID(ID_task_time_loca_impo, task_time_loca_impo);
	int id;
	std::istringstream in(ID);

	if(!(in >> id)){
		CommandUpdate inValidUpdate;
		inValidUpdate.setInvalid();
		return inValidUpdate;
	}

	if(checkFloating(task_time_loca_impo)){
		FloatingEvent* eve = new FloatingEvent;
		eve->setStatus(PENDING);
		eve->setName("\n");
		eve->setImportanceLevel("\n");      // need to change NORMAL to Empty
		eve->setLocation("\n");
		eve->setDisplayID(id);
		CommandUpdate update;
		update.setEvent(eve);
		update.setID(id);
		return update;
	}


	Parser_Importance parserImpo;       
	std::string impo = parserImpo.check(task_time_loca_impo, task_time_loca);

	Parser_Location parserLoc;
	std::string location = parserLoc.check(task_time_loca, task_time);
	task_time = task_time + QUOTE_BLANK_ANALYZER;

	//inserted!!!
	DateTime startT;                   
	DateTime endT;
	EventType etype;
	std::string startTimeString;
	std::string endTimeString;
	std::string startDateString;
	std::string endDateString;
	DateTimeLocator dtl;

	if(dtl.process(task_time, taskS, startTimeString, endTimeString, startDateString, endDateString)){		
		if((startTimeString == QUOTE_ANALYZER) && (endTimeString == QUOTE_ANALYZER)){    //Assert
			etype = SAME;
		}else{
			if(startTimeString == QUOTE_ANALYZER){
				etype = DEADLINE;
			}else{
				etype = TIME;
			}

			fillDateTimeWithTimeString(startT, startTimeString);
			fillDateTimeWithTimeString(endT, endTimeString);
			fillDateTimeWithDateString(startT, startDateString);
			fillDateTimeWithDateString(endT, endDateString);
		}
	}else{      //check the t[...........] format

		size_t stPosTime;
		size_t edPosTime;
		if(findStrictTimePiece(task_time, taskS, stPosTime, edPosTime)){    //find the position of t[....]
			std::string dummy;
			std::string timePiece = task_time.substr(stPosTime, edPosTime-stPosTime);

			if(dtl.process(timePiece, dummy, startTimeString, endTimeString, startDateString, endDateString)){  //locate datetime in t[...]

				if((startTimeString == QUOTE_ANALYZER) && (endTimeString == QUOTE_ANALYZER)){    
					etype = FLOATING;
				}else{

					if(startTimeString == QUOTE_ANALYZER){
						etype = DEADLINE;
					}else{
						etype = TIME;
					}

					fillDateTimeWithTimeString(startT, startTimeString);
					fillDateTimeWithTimeString(endT, endTimeString);
					fillDateTimeWithDateString(startT, startDateString);
					fillDateTimeWithDateString(endT, endDateString);
				}


			}else{
				CommandUpdate update;
				update.setInvalid();
				update.setMessage(ErrorConfuse);
				return update;
			}

		}else{
			CommandUpdate update;
			update.setInvalid();
			update.setMessage(ErrorConfuse);
			return update;
		}
	}

	


	if(etype == TIME){
		TimedEvent* eve = new TimedEvent;
		taskS = clear_Space_Punctuation(taskS);
		eve->setStatus(PENDING);
		if(taskS == QUOTE_ANALYZER){
			eve->setName("\n");

		}else{
			eve->setName(taskS);

		}

		if(task_time_loca_impo == task_time_loca){
			eve->setImportanceLevel("\n");      
		}else{
			eve->setImportanceLevel(impo);
		}

		if(location == QUOTE_ANALYZER){
			eve->setLocation("\n");
		}else{
			eve->setLocation(location);
		}

		eve->setTimedEventStartTime(startT);
		eve->setTimedEventEndTime(endT);
		eve->setDisplayID(id);
		CommandUpdate update;

		if(!DateTimeIsValid(startT)){
			update.setMessage(ErrorWrongTime);
			update.setInvalid();
			return update;
		}

		if(!DateTimeIsValid(endT)){
			update.setMessage(ErrorWrongTime);
			update.setInvalid();
			return update;
		}

		if(!TwoDatesAreInOrder(startT, endT)){
			update.setMessage(ErrorWrongTime);
			update.setInvalid();
			return update;
		}

		update.setEvent(eve);
		update.setID(id);
		return update;

	}else if(etype == DEADLINE){
		DeadlineEvent* eve = new DeadlineEvent;
		taskS = clear_Space_Punctuation(taskS);
		eve->setStatus(PENDING);
		if(taskS == QUOTE_ANALYZER){
			eve->setName("\n");

		}else{
			eve->setName(taskS);

		}

		if(task_time_loca_impo == task_time_loca){
			eve->setImportanceLevel("\n");      
		}else{
			eve->setImportanceLevel(impo);
		}

		if(location == QUOTE_ANALYZER){
			eve->setLocation("\n");
		}else{
			eve->setLocation(location);
		}

		eve->setDeadlineEventEndtime(endT);
		eve->setDisplayID(id);
		CommandUpdate update;

		if(!DateTimeIsValid(endT)){
			update.setMessage(ErrorWrongTime);
			update.setInvalid();
			return update;
		}

		update.setEvent(eve);
		update.setID(id);
		return update;

	}else{
		SameTypeEvent* eve = new SameTypeEvent;
		taskS = clear_Space_Punctuation(taskS);
		eve->setStatus(PENDING);
		if(taskS == QUOTE_ANALYZER){
			eve->setName("\n");

		}else{
			eve->setName(taskS);

		}

		if((task_time_loca_impo == task_time_loca)){
			eve->setImportanceLevel("\n");      
		}else{
			eve->setImportanceLevel(impo);
		}

		if(location == QUOTE_ANALYZER){
			eve->setLocation("\n");
		}else{
			eve->setLocation(location);
		}
		eve->setDisplayID(id);
		CommandUpdate update;
		update.setEvent(eve);
		update.setID(id);
		return update;
	}

}

//@author A0105730U
CommandSearch Analyzer::intepret_Search (std::string input){
	if(input == QUOTE_ANALYZER){
		CommandSearch invalidSearch;
		invalidSearch.setInvalid();
		return invalidSearch;
	}else{
		CommandSearch search;
		search.setSearchContent(input);
		return search;
	}
}


//@author A0105730U
CommandDisplay Analyzer::intepret_Display(std::string input){
	CommandDisplay display;
	std::string taskS;
	std::vector<std::string> dateVec;
	std::vector<std::size_t> posStart;
	std::vector<std::size_t> posEnd;
	size_t s;
	DateTime startT;
	DateTime endT;

	DateTimeLocator dtl;

	dtl.detectDatePiece(input,s,dateVec, posStart, posEnd);

	if(dateVec.size() == 0){
		startT.setEmpty(false);
		endT.setEmpty(false);
		startT.setDate(1,1,1900);
		endT.setDate(1,1,2100);
	}else if(dateVec.size() == 1){
		fillDateTimeWithDateString(startT, dateVec[0]);
		fillDateTimeWithDateString(endT, dateVec[0]);
	}else{
		if(posStart[0]>posStart[1]){
			std::string temp = dateVec[0];
			dateVec[0] = dateVec[1];
			dateVec[1] = temp;
		}


		fillDateTimeWithDateString(startT, dateVec[0]);
		fillDateTimeWithDateString(endT, dateVec[1]);
	}

	display.setStartDate(startT);
	display.setEndDate(endT);

	if(!TwoDatesAreInOrder(startT, endT)){
		display.setMessage(ErrorWrongTime);
		display.setInvalid();
			return display;
		}

	return display;

}


//@author A0105730U
//API function of Analyzer, take in a userinput, pass a command to executer, and return a feedback(got from executer) to UI
Feedback Analyzer::process_Analyzer(std::string userInput){
	std::string instruction;
	std::string content;

	userInput = clear_Space_Punctuation(userInput);
	splitInput(userInput, instruction, content);
	Logger::instance()->LogMessage(LOG_MESSAGE_ONE_ANALYZER);

	if(instruction == UNDO_ANALYZER){
		Logger::instance()->LogMessage(LOG_MESSAGE_TWO_ANALYZER);
		return _theE.undo();
	}

	CommandType type = getCommandType(instruction);
	Logger::instance()->LogMessage(LOG_MESSAGE_THREE_ANALYZER);

	switch(type){
	case CommandTypeRead:{
		CommandRead* read = new CommandRead;
		_theE.storeCommand(read);
		Logger::instance()->LogMessage(LOG_MESSAGE_FOUR_ANALYZER);
		return _theE.executeCommand();
		break;
						 }

	case CommandTypeCheck:{
		CommandCheck* statusUpdate = new CommandCheck;
		_theE.storeCommand(statusUpdate);
		Logger::instance()->LogMessage(LOG_MESSAGE_FIVE_ANALYZER);
		return _theE.executeCommand();
		break;
						  }

	case CommandTypeAdd:{
		CommandAdd* add = new CommandAdd;
		*add = intepret_Add (content);
		if(add->isValid()){
			_theE.storeCommand(add);
			Logger::instance()->LogMessage(LOG_MESSAGE_SIX_ANALYZER);
			return _theE.executeCommand();
		}else{
			CommandInvalid* invalid = new CommandInvalid;
			invalid->setMessage(add->getMessage());
			_theE.storeCommand(invalid);
			Logger::instance()->LogMessage(LOG_MESSAGE_SEVEN_ANALYZER);
			return _theE.executeCommand();
		}
		break;
						}

	case CommandTypeDelete:{
		CommandDelete* del = new CommandDelete;
		*del = intepret_Delete (content);
		if(del->isValid()){
			_theE.storeCommand(del);
			Logger::instance()->LogMessage(LOG_MESSAGE_EIGHT_ANALYZER);
			return _theE.executeCommand();
		}else{
			CommandInvalid* invalid = new CommandInvalid;
			invalid->setMessage(del->getMessage());
			_theE.storeCommand(invalid);
			Logger::instance()->LogMessage(LOG_MESSAGE_NINE_ANALYZER);
			return _theE.executeCommand();
		}
		break;
						   }


	case CommandTypeMark:{
		CommandMark* mark = new CommandMark;
		*mark = intepret_Mark (content);
		if(mark->isValid()){
			_theE.storeCommand(mark);
			Logger::instance()->LogMessage(LOG_MESSAGE_TEN_ANALYZER);
			return _theE.executeCommand();
		}else{
			CommandInvalid* invalid = new CommandInvalid;
			invalid->setMessage(mark->getMessage());
			_theE.storeCommand(invalid);
			Logger::instance()->LogMessage(LOG_MESSAGE_ELEVEN_ANALYZER);
			return _theE.executeCommand();
		}
		break;
						 }


	case CommandTypeUpdate:{
		CommandUpdate* update = new CommandUpdate;
		*update = intepret_Update (content);    //same as add, just add an ID
		if(update->isValid()){
			_theE.storeCommand(update);
			Logger::instance()->LogMessage(LOG_MESSAGE_TWELVE_ANALYZER);
			return _theE.executeCommand();
		}else{
			CommandInvalid* invalid = new CommandInvalid;
			invalid->setMessage(update->getMessage());
			_theE.storeCommand(invalid);
			Logger::instance()->LogMessage(LOG_MESSAGE_THIRTEEN_ANALYZER);
			return _theE.executeCommand();
		}
		break;
						   }

	case CommandTypeSearch:{
		CommandSearch *search = new CommandSearch;
		*search = intepret_Search (content);    //content can be empty, shuyu need to detect it
		if(search->isValid()){
			_theE.storeCommand(search);
			Logger::instance()->LogMessage(LOG_MESSAGE_FOURTEEN_ANALYZER);
			return _theE.executeCommand();
		}else{
			CommandInvalid* invalid = new CommandInvalid;
			invalid->setMessage(search->getMessage());
			_theE.storeCommand(invalid);
			Logger::instance()->LogMessage(LOG_MESSAGE_FIFTEEN_ANALYZER);
			return _theE.executeCommand();
		}
		break;
						   }

	case CommandTypeDisplay:{
		CommandDisplay *display = new CommandDisplay;
		*display = intepret_Display (content);
		if(display->isValid()){         
			_theE.storeCommand(display);
			Logger::instance()->LogMessage(LOG_MESSAGE_SIXTEEN_ANALYZER);
			return _theE.executeCommand();
		}else{
			CommandInvalid* invalid = new CommandInvalid;
			invalid->setMessage(display->getMessage());
			_theE.storeCommand(invalid);
			Logger::instance()->LogMessage(LOG_MESSAGE_EIGHTEEN_ANALYZER);
			return _theE.executeCommand();
		}
		break;
							}

	default:{
		CommandInvalid* invalid= new CommandInvalid;
		invalid->setMessage(ErrorFormat);
		_theE.storeCommand(invalid);
		Logger::instance()->LogMessage(LOG_MESSAGE_NINETEEN_ANALYZER);
		return _theE.executeCommand();

		break;
			}	 
	}
}




Analyzer::~Analyzer(void)
{
}





